// PropertyVariable.cpp: implementation of the PropertyVariable class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "PropertyVariable.h"
#include "Part.h"
#include "supporthanger.h"
#include "SimpleExpression.h"
#include "PropertyFactory.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

namespace PropertySystem
{
	UE_IMPLEMENT_DYNAMIC(PropertyVariable, Variable);

	PropertyVariable::PropertyVariable()
	{
		m_pCVariable = NULL;
		m_pOwner = NULL;
		m_nEffectField = ePART;
		m_bIsCustom = FALSE;
		m_bIsCheckEffect = FALSE;
		m_bIsCheckExist = FALSE;
		m_bIsSave = FALSE;
		m_bIsInitState = FALSE;
	}
	
	PropertyVariable::~PropertyVariable()
	{
		
	}

	void PropertyVariable::CopyPropertyData(PropertyVariable& destinction, PropertyVariable& source)
	{
		if(source.GetSymbol() == PropertyFactory::PARTIDPRONAME ||
			source.GetSymbol() == PropertyFactory::DESCRIPTION ||
			source.GetSymbol() == PropertyFactory::STANDARD ||
			source.GetSymbol() == PropertyFactory::SPEC)
		{
			*static_cast<Variable*>(&destinction) = *static_cast<Variable*>(&source);
		}
		destinction.Symbol(source.GetSymbol());
		destinction.DataType(source.DataType());
		destinction.m_pCVariable = source.m_pCVariable;
		destinction.m_strDefault = source.m_strDefault;
		destinction.m_strDesc = source.m_strDesc;
		destinction.m_strUnit = source.m_strUnit;
		destinction.m_nEffectField = source.m_nEffectField;
		destinction.m_nPropertyStyle = source.m_nPropertyStyle;
		destinction.m_strEffectCondition = source.m_strEffectCondition;
		destinction.m_strExistCondition = source.m_strExistCondition;
		destinction.m_bIsSave = source.m_bIsSave;
	}

	void PropertyVariable::RegisterEffect()
	{
		ASSERT(m_nEffectField != -1);
		ASSERT(m_pOwner);
		ASSERT(static_cast<Part*>(m_pOwner)->SupportHangerOwner());

		switch(m_nEffectField)
		{
		case ePART:break;
//		case eSTRING:m_pOwner->GetOwner()->AddProperty(this);break;
		case eSUPPORTHANGER:static_cast<Part*>(m_pOwner)->SupportHangerOwner()->AddProperty(this);break;
		}
	}

	void PropertyVariable::UnRegisterEffect()
	{
		ASSERT(m_nEffectField != -1);
		ASSERT(m_pOwner);
//		ASSERT(m_pOwner->GetOwner());
		ASSERT(static_cast<Part*>(m_pOwner)->SupportHangerOwner());

		switch(m_nEffectField)
		{
		case ePART:break;
//		case eSTRING:m_pOwner->GetOwner()->RemoveProperty(this->GetSymbol());break;
		case eSUPPORTHANGER:static_cast<Part*>(m_pOwner)->SupportHangerOwner()->RemoveProperty(this->GetSymbol());break;
		}
	}
	
	BOOL PropertyVariable::IsEffect()
	{
		if(GetOwner() == NULL || m_strEffectCondition.IsEmpty() || m_bIsCheckEffect)
			return TRUE;

		m_bIsCheckEffect = TRUE;
		SimpleExpression expr(m_strEffectCondition, GetOwner()->GetPropertyStack());

		Variable var = expr.Caculate();

		m_bIsCheckEffect = FALSE;
		return (BOOL)var;
	}

	BOOL PropertyVariable::IsExist()
	{
		if(GetOwner() == NULL || m_strExistCondition.IsEmpty() || m_bIsCheckExist)
			return TRUE;

		m_bIsCheckExist = TRUE;
		SimpleExpression expr(m_strExistCondition, GetOwner()->GetPropertyStack());
		
		Variable var = expr.Caculate();

		m_bIsCheckExist = FALSE;
		return (BOOL)var;
	}

	Variable& PropertyVariable::operator=(const CString& Value)
	{
		Variable::operator =(Value);
		if(GetOwner() != NULL)
		{
			if(GetOwner()->IsReadState())
			{
				GetOwner()->SetModify();
			}
			GetOwner()->SetUpdateObserver();
			GetOwner()->RunGetPropertyTrigger();
		}
		return *this;
	}

	Variable& PropertyVariable::operator=(const Variable& Value)
	{
		(CString)(*const_cast<Variable*>(&Value));;
		Variable::operator =(Value);
		if(GetOwner() != NULL)
		{
			if(GetOwner()->IsReadState())
			{
				GetOwner()->SetModify();
			}
			GetOwner()->SetUpdateObserver();
			GetOwner()->RunGetPropertyTrigger();
		}
		return *this;
	}

	Variable& PropertyVariable::operator=(const _variant_t& Value)
	{
		Variable::operator =(Value);
		if(GetOwner() != NULL)
		{
			if(GetOwner()->IsReadState())
			{
				GetOwner()->SetModify();
			}
			GetOwner()->SetUpdateObserver();
			GetOwner()->RunGetPropertyTrigger();
		}
		return *this;
	}

	Variable& PropertyVariable::operator=(const INT& Value)
	{
		Variable::operator =(Value);
		if(GetOwner() != NULL)
		{
			if(GetOwner()->IsReadState())
			{
				GetOwner()->SetModify();
			}
			GetOwner()->SetUpdateObserver();
			GetOwner()->RunGetPropertyTrigger();
		}
		return *this;
	}

	Variable& PropertyVariable::operator=(const DOUBLE& Value)
	{
		Variable::operator =(Value);
		if(GetOwner() != NULL)
		{
			if(GetOwner()->IsReadState())
			{
				GetOwner()->SetModify();
			}
			GetOwner()->SetUpdateObserver();
			GetOwner()->RunGetPropertyTrigger();
		}
		return *this;
	}

	Variable& PropertyVariable::operator=(const LONG& Value)
	{
		Variable::operator =(Value);
		if(GetOwner() != NULL)
		{
			if(GetOwner()->IsReadState())
			{
				GetOwner()->SetModify();
			}
			GetOwner()->SetUpdateObserver();
			GetOwner()->RunGetPropertyTrigger();
		}
		return *this;
	}

	Variable& PropertyVariable::operator=(const SHORT& Value)
	{
		Variable::operator =(Value);
		if(GetOwner() != NULL)
		{
			if(GetOwner()->IsReadState())
			{
				GetOwner()->SetModify();
			}
			GetOwner()->SetUpdateObserver();
			GetOwner()->RunGetPropertyTrigger();
		}
		return *this;
	}

	Variable& PropertyVariable::operator=(const FLOAT& Value)
	{
		Variable::operator =(Value);
		if(GetOwner() != NULL)
		{
			if(GetOwner()->IsReadState())
			{
				GetOwner()->SetModify();
			}
			GetOwner()->SetUpdateObserver();
			GetOwner()->RunGetPropertyTrigger();
		}
		return *this;
	}

	Variable PropertyVariable::operator-()
	{
		Variable::operator -();
		if(GetOwner() != NULL)
		{
			if(GetOwner()->IsReadState())
			{
				GetOwner()->SetModify();
			}
			GetOwner()->SetUpdateObserver();
			GetOwner()->RunGetPropertyTrigger();
		}
		return *this;
	}

	PropertyVariable::operator DOUBLE ()
	{
		if(!IsKnown() || !IsEffect())
		{
			InitValue();
		}
		return Variable::operator DOUBLE();
	}

	PropertyVariable::operator FLOAT()
	{
		if(!IsKnown() || !IsEffect())
		{
			InitValue();
		}
		return Variable::operator FLOAT();
	}

	PropertyVariable::operator _variant_t()
	{
		if(!IsKnown() || !IsEffect())
		{
			InitValue();
		}
		return Variable::operator _variant_t();
	}

	PropertyVariable::operator LONG()
	{
		if(!IsKnown() || !IsEffect())
		{
			InitValue();
		}
		return Variable::operator LONG();
	}

	PropertyVariable::operator INT()
	{
		if(!IsKnown() || !IsEffect())
		{
			InitValue();
		}
		return Variable::operator INT();
	}

	PropertyVariable::operator SHORT()
	{
		if(!IsKnown() || !IsEffect())
		{
			InitValue();
		}
		return Variable::operator SHORT();
	}

	PropertyVariable::operator CString()
	{
		if(!IsKnown() || !IsEffect())
		{
			InitValue();
		}
		return Variable::operator CString();
	}

};